﻿#pragma once
//-------------------------------------------
// QFont class
//-------------------------------------------

namespace micro{
namespace gui{


class QLogFont : public LOGFONT
{
public:
	QLogFont()
	{
		memset(this, 0, sizeof(LOGFONT));
	}

	QLogFont(const LOGFONT& lf)
	{
		Copy(&lf);
	}

	QLogFont(HFONT hFont)
	{
		//ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
		::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
	}

	HFONT CreateFontIndirect()
	{
		return ::CreateFontIndirect(this);
	}

	void SetBold()
	{
		lfWeight = FW_BOLD;
	}

	bool IsBold() const
	{
		return (lfWeight >= FW_BOLD);
	}

	void MakeBolder(int iScale = 1)
	{
		lfWeight += FW_BOLD * iScale;
	}

	void MakeLarger(int iScale = 1)
	{
		if(lfHeight > 0)
			lfHeight += iScale;
		else
			lfHeight -= iScale;
	}

	void SetHeight(LONG nPointSize, HDC hDC = nullptr)
	{
		// For MM_TEXT mapping mode
		lfHeight = -::MulDiv(nPointSize, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
	}

	LONG GetHeight(HDC hDC = nullptr) const
	{
		// For MM_TEXT mapping mode
		return ::MulDiv(-lfHeight, 72, ::GetDeviceCaps(hDC, LOGPIXELSY));
	}

	LONG GetDeciPointHeight(HDC hDC = nullptr) const
	{
#ifndef _WIN32_WCE
		POINT ptOrg = { 0, 0 };
		::DPtoLP(hDC, &ptOrg, 1);
		POINT pt = { 0, 0 };
		pt.y = abs(lfHeight) + ptOrg.y;
		::LPtoDP(hDC,&pt,1);
		return ::MulDiv(pt.y, 720, ::GetDeviceCaps(hDC, LOGPIXELSY));   // 72 points/inch, 10 decipoints/point
#else // CE specific
		// DP and LP are always the same on CE
		return ::MulDiv(abs(lfHeight), 720, ::GetDeviceCaps(hDC, LOGPIXELSY));   // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
	}

	void SetHeightFromDeciPoint(LONG nDeciPtHeight, HDC hDC = nullptr)
	{
#ifndef _WIN32_WCE
		POINT pt = { 0, 0 };
		pt.y = ::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720);   // 72 points/inch, 10 decipoints/point
		::DPtoLP(hDC, &pt, 1);
		POINT ptOrg = { 0, 0 };
		::DPtoLP(hDC, &ptOrg, 1);
		lfHeight = -abs(pt.y - ptOrg.y);
#else // CE specific
		// DP and LP are always the same on CE
		lfHeight = -abs(::MulDiv(::GetDeviceCaps(hDC, LOGPIXELSY), nDeciPtHeight, 720));   // 72 points/inch, 10 decipoints/point
#endif // _WIN32_WCE
	}

#ifndef _WIN32_WCE
	void SetCaptionFont()
	{
		NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
		//ATLVERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0));
		Copy(&ncm.lfCaptionFont);
	}

	void SetMenuFont()
	{
		NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
		 ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0) ;
		Copy(&ncm.lfMenuFont);
	}

	void SetStatusFont()
	{
		NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
		::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0) ;
		Copy(&ncm.lfStatusFont);
	}

	void SetMessageBoxFont()
	{
		NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
		::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
		Copy(&ncm.lfMessageFont);
	}
#endif // !_WIN32_WCE

	void Copy(const LOGFONT* pLogFont)
	{
		//ATLASSERT(pLogFont != nullptr);
		*(LOGFONT*)this = *pLogFont;
	}
	operator LPLOGFONT(){ return  this;} 
	//operator LOGFONT()  { return  *this;} 

	QLogFont& operator =(const QLogFont& src)
	{
		Copy(&src);
		return *this;
	}

	QLogFont& operator =(const LOGFONT& src)
	{
		Copy(&src);
		return *this;
	}

	QLogFont& operator =(HFONT hFont)
	{
		//ATLASSERT(::GetObjectType(hFont) == OBJ_FONT);
		::GetObject(hFont, sizeof(LOGFONT), (LOGFONT*)this);
		return *this;
	}

	bool operator ==(const LOGFONT& logfont) const
	{
		return(logfont.lfHeight == lfHeight &&
		       logfont.lfWidth == lfWidth &&
		       logfont.lfEscapement == lfEscapement &&
		       logfont.lfOrientation == lfOrientation &&
		       logfont.lfWeight == lfWeight &&
		       logfont.lfItalic == lfItalic &&
		       logfont.lfUnderline == lfUnderline &&
		       logfont.lfStrikeOut == lfStrikeOut &&
		       logfont.lfCharSet == lfCharSet &&
		       logfont.lfOutPrecision == lfOutPrecision &&
		       logfont.lfClipPrecision == lfClipPrecision &&
		       logfont.lfQuality == lfQuality &&
		       logfont.lfPitchAndFamily == lfPitchAndFamily &&
		       lstrcmp(logfont.lfFaceName, lfFaceName) == 0);
	}
};

class QFont
{
public:
	HFONT m_hFont;

	QFont(HFONT hFont = nullptr) {  m_hFont=hFont;}

	~QFont()
	{
		if(m_hFont != nullptr)
		{
			::DeleteObject(m_hFont);
			m_hFont = nullptr;
		}
	}

public:
	
	operator HFONT() {return m_hFont;}  
	HFONT  GetFont(){ return m_hFont;}
	
	void Attach(HFONT hFont)
	{
		if( m_hFont != nullptr)
			::DeleteObject(m_hFont);
		m_hFont = hFont;
	}
	
	HFONT Detach()
	{
		HFONT hFont = m_hFont;
		m_hFont = nullptr;
		return hFont;
	}

	void DeleteObject()
	{
		if( m_hFont != nullptr)
			::DeleteObject(m_hFont);
	}
	
	HFONT CreateFontIndirect(const LOGFONT* lpLogFont)
	{
		ASSERT(m_hFont == nullptr);
		m_hFont = ::CreateFontIndirect(lpLogFont);
		return m_hFont;
	}


	HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
			int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline,
			BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision,
			BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily,
			LPCTSTR lpszFacename)
	{
		ASSERT(m_hFont == nullptr);
		m_hFont = ::CreateFont(nHeight, nWidth, nEscapement,
			nOrientation, nWeight, bItalic, bUnderline, cStrikeOut,
			nCharSet, nOutPrecision, nClipPrecision, nQuality,
			nPitchAndFamily, lpszFacename);
		return m_hFont;
	}
	
	
	BOOL GetStockFont( int nStockFont )
	{
	
		HFONT hFont = ( HFONT )::GetStockObject( nStockFont );
		if ( !hFont) 	return FALSE;
		Attach( hFont );
		return TRUE;
	}


	int GetLogFont(LOGFONT* pLogFont) 
	{
		ASSERT(m_hFont != nullptr);
		return ::GetObject(m_hFont, sizeof(LOGFONT), pLogFont);
	}
	
	bool GetLogFont(LOGFONT& LogFont) 
	{
		ASSERT(m_hFont != nullptr);
		return (::GetObject(m_hFont, sizeof(LOGFONT), &LogFont) == sizeof(LOGFONT));
	}
};


}


}//micro